package file

import (
	"fmt"
	"net/url"
	"os"
	"strings"

	"gitee.com/miajio/fyleos/pro/cache"
	"gitee.com/miajio/go-base-util/pkg/file"
	"gitee.com/miajio/go-base-util/pkg/ginx"
	"github.com/gin-gonic/gin"
)

func getChildren(c *gin.Context) {
	path := c.Query("path")
	var err error

	var nowFile *file.File
	if path == "" {
		nowFile = cache.RootFile
	} else {
		path = formatPath(path)
		theFile, err := file.New(cache.OpenPath + path)
		if err != nil {
			cache.Log.Errorf("get path %s fail: %v", path, err)
			ginx.Fail(c, 5003, "get path fail", fmt.Errorf("get path %s fail: %v", path, err), ginx.ReturnJsonp)
			return
		}
		nowFile = theFile
	}

	children, err := nowFile.GetChildren()
	if err != nil {
		cache.Log.Errorf("get root children fail: %v", err)
		ginx.Fail(c, 5001, "get root children fail", fmt.Errorf("get root children fail: %v", err), ginx.ReturnJsonp)
		return
	}
	var result []FileResponse

	for i := range children {
		file := children[i]
		r := FileResponse{
			Name:   file.GetName(),
			Suffix: file.GetSuffix(),
			Path:   hiddinSysPath(file.GetPath()),
			IsDir:  file.IsDir(),
		}
		result = append(result, r)
	}
	ginx.Success(c, "success", result, ginx.ReturnJsonp)
}

func remove(c *gin.Context) {
	path := c.Query("path")
	if path == "" {
		ginx.Fail(c, 40001, "param path is empty", nil, ginx.ReturnJsonp)
		return
	}
	nowFile, err := file.New(cache.OpenPath + path)
	if err != nil {
		cache.Log.Errorf("get path %s fail: %v", path, err)
		ginx.Fail(c, 5003, "get path fail", fmt.Errorf("get path %s fail: %v", path, err), ginx.ReturnJsonp)
		return
	}
	if err := nowFile.Remove(); err != nil {
		cache.Log.Errorf("remove path %s fail: %v", path, err)
		ginx.Fail(c, 5003, "remove path fail", fmt.Errorf("remove path %s fail: %v", path, err), ginx.ReturnJsonp)
		return
	}
	ginx.Success(c, "success", fmt.Sprintf("path %s remove success", path), ginx.ReturnJsonp)
}

func download(c *gin.Context) {
	path := c.Query("path")
	if path == "" {
		ginx.Fail(c, 40001, "param path is empty", nil, ginx.ReturnJsonp)
		return
	}
	path = formatPath(path)
	f, err := os.Stat(cache.OpenPath + path)
	if err != nil || f.IsDir() {
		ginx.Fail(c, 5002, fmt.Sprintf("download fail path %s not a file", path), nil, ginx.ReturnJsonp)
		return
	}

	fileName := f.Name()

	c.Header("Content-Type", "application/octet-stream")
	c.Header("Content-Disposition", fmt.Sprintf("attachment; filename*=utf-8''%s", url.QueryEscape(fileName)))
	c.Header("Content-Transfer-Encoding", "binary")
	c.File(cache.OpenPath + path)
}

func upload(c *gin.Context) {
	path := c.PostForm("path")
	fyle, err := c.FormFile("file")
	if err != nil {
		ginx.Fail(c, 5003, fmt.Sprintf("upload fail, file param: %v", err), err, ginx.ReturnJsonp)
		return
	}
	filePath := cache.OpenPath + formatPath(path)

	if f, err := file.New(filePath); err != nil || !f.IsDir() {
		ginx.Fail(c, 5002, fmt.Sprintf("upload fail, path not a dir: %s or err: %v", formatPath(path), err), err, ginx.ReturnJsonp)
		return
	}

	if err := c.SaveUploadedFile(fyle, filePath+fyle.Filename); err != nil {
		ginx.Fail(c, 5003, fmt.Sprintf("upload fail, path %s err: %v", formatPath(path), err), err, ginx.ReturnJsonp)
		return
	}
	ginx.Success(c, "文件上传成功", nil, ginx.ReturnJsonp)
}

func hiddinSysPath(path string) string {
	return path[len(cache.OpenPath):]
}

func formatPath(path string) string {
	path = strings.ReplaceAll(path, "\\", "/")
	path = strings.ReplaceAll(path, "..", "")
	if strings.Index(path, "/") != 0 {
		path = "/" + path
	}
	return path
}
